<!--
用于修改单值的对话框,这个组件放在q-app这个div下方,整个程序就一个
-->
<template>
  <q-dialog v-model="$d.isDialogShowing" :persistent="checkIfNeedPersistent" transition-show="none"
    transition-hide="none">
    <q-card :style="boxStyle">
      <q-card-section class="q-px-sm q-pt-sm q-pb-none">
        <q-banner class="text-white bg-red q-mb-sm" dense inline-actions v-if="serverErrorMessage">
          {{serverErrorMessage}}
          <template v-slot:action>
            <q-btn @click="serverErrorMessage = null" dense flat icon="close" size="sm" />
          </template>
        </q-banner>
        <div>{{$d.text}}</div>
        <q-input :error="v$.valToChange.$error" :error-message="e$(v$.valToChange.$errors)" :hide-bottom-space="true"
          dense
          no-error-icon outlined square stack-label v-model="form.valToChange" autofocus @focus="ui.select"
          @keyup.enter="onOkButtonClick" :readonly="$d.activating" clearable>
          <q-menu v-if="$d.showDatePicker" :fit="false" ref="dtContainer" transition-hide="none"
            transition-show="none">
            <q-date :title="form.valToChange" @update:model-value="()=>{$refs['dtContainer'].hide()}"
              mask="YYYY-MM-DD" no-unset
              :subtitle="$t('当前选中日期')" today-btn v-model="form.valToChange" />
          </q-menu>
          <template v-slot:append>
            <q-icon v-if="$d.showDatePicker" name="event" />
          </template>
        </q-input>
      </q-card-section>
      <q-card-actions align="right">
        <q-btn color="primary" @click="onOkButtonClick" :disable="isButtonDisabled" :loading="$d.activating">{{$t('确定')}}
          <template v-slot:loading>
            <q-spinner />&nbsp;{{$t('确定')}}
          </template>
        </q-btn>
        <q-btn unelevated color="primary" @click="onCancelButtonClick" :disable="isButtonDisabled" outline>{{$t('取消')}}
        </q-btn>
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>

<script lang="ts">
export default {
  name: 'singleInputBox'
}
</script>

<script lang="ts" setup>

import {computed, reactive, Ref, ref} from 'vue'
import useVuelidate, {ValidationArgs} from '@vuelidate/core'
import {SingleInputBoxParams} from '../defs/comm'
import {QMenu} from 'quasar'
import {useI18n} from 'vue-i18n'

// 服务器错误信息
const serverErrorMessage = ref('')

// 样式，宽度
const boxStyle = reactive({
  'min-width': '400px'
})

// 默认的noRule验证规则(即无验证规则)
const noRule: ValidationArgs = {
  valToChange: {
    alwaysRight: $f.validators.alwaysRight
  }
}

// 验证规则
const rules = computed(() => {
  if (rulesFromParams.value) {
    return rulesFromParams.value
  }
  return noRule
})

let rulesFromParams: Ref<ValidationArgs | null> = ref(null)

const $d = reactive({
  // 对话框是否展示
  isDialogShowing: false,
  // 当前是否处于活动状态
  activating: false,
  // 是否需要保持
  persistent: false,
  // 显示的提示文本
  text: '',
  // 是否显示时间日期选择器
  showDatePicker: false,
  // 回调方法，参数带入
  callback: null as ((val: string, setResult: (success: boolean, errMsg?: string) => void) => void) | null
})

//表单
const form = reactive({
  // 就是输入框的绑定值了
  valToChange: ''
})

const v$ = useVuelidate(rules, form, {$autoDirty: true})

const checkIfNeedPersistent = computed(() => $d.activating || $d.persistent)
const isButtonDisabled = computed(() => $d.activating)

// 显示服务器出错信息
const setServerErrorMessage = function (errMsg: string) {
  $d.activating = false
  serverErrorMessage.value = errMsg
}

// 关闭对话框
const hideSingleInputBox = function () {
  $d.activating = false
  $d.isDialogShowing = false
}

const {t} = useI18n()
// 接收回调结果
const setResult = function (success: boolean, message?: string) {
  if (success) {
    hideSingleInputBox()
  } else {
    setServerErrorMessage(message ?? t('未知错误'))
  }
}

// 弹出singleInputBox,并创建promise对象
const showSingleInputBox = function (param: SingleInputBoxParams) {
  if ($d.isDialogShowing && !$d.activating) {
    return
  }

  $d.isDialogShowing = false
  $d.activating = false
  serverErrorMessage.value = ''
  $d.text = param.text ?? t('请输入')
  if (param.valRule) {
    rulesFromParams.value = {
      valToChange: param.valRule
    }
  } else {
    rulesFromParams.value = noRule
  }

  boxStyle['min-width'] = param.width ? (param.width.toString() + 'px') : '250px'
  $d.persistent = param.persistent ?? false
  form.valToChange = param.defVal ?? ''
  $d.showDatePicker = param.showDatePicker ?? false
  $d.callback = param.callback
  $d.isDialogShowing = true
}

// 点OK按钮
const onOkButtonClick = function () {
  if ($d.activating) {
    return
  }
  void v$.value
    .$validate()
    .then((valRes) => {
      if (valRes) {
        $d.activating = true
        if (typeof $d.callback === 'function') {
          $d.callback(form.valToChange, setResult)
        }
      }
    })
}

// 点击取消按钮
const onCancelButtonClick = function () {
  $d.isDialogShowing = false
}

$f.ui.singleInputBox = showSingleInputBox

const ui = $f.ui
const e$ = $f.getFieldErrStr

</script>
